package yancy.modules.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonProperty;
import yancy.common.exception.RRException;
import yancy.common.utils.JSONUtil;
import yancy.common.utils.R;
import yancy.modules.sys.entity.SysFile;
import yancy.modules.sys.service.SysFileService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

@RestController
@RequestMapping("sys/file")
public class SysFileController extends AbstractController {

    @Autowired
    private SysFileService fileService;

    /**
     * 上传文件
     */
    @RequestMapping("/login")
    public R login() throws Exception {
//        if (file.isEmpty()) {
//            throw new RRException("上传文件不能为空");
//        }
        RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
        //上传文件
        // token bJfLQfH0qVIuKsBzeL2fiIq7AK1FpRJS
        MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();

        parts.add("username", "yyancy517");
        parts.add("password", "andy410781");
        HttpHeaders headers = new HttpHeaders();
        headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");

        HttpEntity formEntity = new HttpEntity(parts, headers);

        String response = template.postForObject("https://sm.ms/api/v2/token", formEntity, String.class);
        return R.ok().put("url", response);
    }
    // {"success":true,"code":"success","message":"Upload success.","data":{"file_id":0,"width":1920,"height":1080,"filename":"7d585680cadd3406736e73904779292e--819505604.jpg","storename":"JA1DuHgqRz2Q7OK.jpg","size":1372702,"path":"\/2021\/07\/26\/JA1DuHgqRz2Q7OK.jpg","hash":"sgKGAtEnHX3efb7QoYwCILWSOR","url":"https:\/\/i.loli.net\/2021\/07\/26\/JA1DuHgqRz2Q7OK.jpg","delete":"https:\/\/sm.ms\/delete\/sgKGAtEnHX3efb7QoYwCILWSOR","page":"https:\/\/sm.ms\/image\/JA1DuHgqRz2Q7OK"},"RequestId":"614696E0-F5FE-4C56-ACE9-B8E5F80FD306"}
    // {"success":false,"code":"image_repeated","message":"Image upload repeated limit, this image exists at: https:\/\/i.loli.net\/2021\/07\/26\/8XQDFWfM34trqac.png","images":"https:\/\/i.loli.net\/2021\/07\/26\/8XQDFWfM34trqac.png","RequestId":"F90E9E5B-0707-47AE-A1E1-45A7BEFAAE3C"}

    @Data
    public static class smFileResp {
        /**
         * "success": true,
         * "code": "success",
         * "message": "Get list success.",
         * "data": [
         * {
         * "file_id": 0,
         * "width": 4677,
         * "height": 3307,
         * "filename": "luo.jpg",
         * "storename": "D5VpWCKFElUsPcR.jpg",
         * "size": 801933,
         * "path": "/2019/12/16/D5VpWCKFElUsPcR.jpg",
         * "hash": "Q6vLIbCGZojrMhO2e7BmgFuXRV",
         * "created_at": 1564844329,
         * "url": "https://i.loli.net/2019/12/16/D5VpWCKFElUsPcR.jpg",
         * "delete": "https://sm.ms/delete/Q6vLIbCGZojrMhO2e7BmgFuXRV",
         * "page": "https://sm.ms/image/D5VpWCKFElUsPcR"
         * }
         * ],
         * "RequestId": "8A84DDCA-96B3-4363-B5DF-524E95A5201A"
         */
        boolean success;
        String code;
        String message;
        Data data;
        @JsonProperty("RequestId")
        String requestId;
        // used by repeated image  file
        String images;

        @lombok.Data
        public static class Data {
            Integer file_id;
            Integer width;
            Integer height;
            String filename;
            String storename;
            Long size;
            String path;
            String hash;
            String created_at;
            String url;
            String delete;
            String page;
        }


    }

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public R upload2(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
        //上传文件
        // token bJfLQfH0qVIuKsBzeL2fiIq7AK1FpRJS
        MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
        ByteArrayResource fileAsResource = new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }
        };
        parts.add("smfile", fileAsResource);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
        headers.add("Authorization", "bJfLQfH0qVIuKsBzeL2fiIq7AK1FpRJS");

        HttpEntity formEntity = new HttpEntity(parts, headers);

        String response = template.postForObject("https://sm.ms/api/v2/upload", formEntity, String.class);
        smFileResp smFileResp = JSONUtil.JSONToObj(response, smFileResp.class);
        System.out.println(smFileResp);

//        SysFile sysFile = new SysFile();
//        sysFile.setFilename(file.getOriginalFilename());
//        sysFile.setUrl(smFileResp.getData().getUrl());
//        sysFile.setCreateUserId(getUserId());
//        sysFile.setCreateTime(new Date());
//
//        fileService.save(sysFile);
        Long fileId = handleResponse(file, smFileResp);
        return fileId == null ? R.error("上传失败") : R.ok().put("fileId", fileId);
    }

    Map<String, BiFunction<MultipartFile, smFileResp, Long>> handlers = new HashMap<>();


    Long handleResponse(MultipartFile file, smFileResp resp) {
        BiFunction<MultipartFile, smFileResp, Long> handler = handlers.get(resp.getCode());
        if (handler != null) {
            return handler.apply(file, resp);
        }
        return null;
    }

    @PostConstruct
    void initiateHandlers() {
        BiFunction<MultipartFile, smFileResp, Long> handlerSuccess = (file, resp) -> {
            SysFile sysFile = new SysFile();
            sysFile.setFilename(file.getOriginalFilename());
            sysFile.setUrl(resp.getData().getUrl());
            sysFile.setCreateUserId(getUserId());
            sysFile.setCreateTime(new Date());

            fileService.save(sysFile);
            return sysFile.getFileId();
        };

        BiFunction<MultipartFile, smFileResp, Long> handlerRepeated = (file, resp) -> {
            SysFile existedFile = fileService
                    .getOne(new QueryWrapper<SysFile>().eq("url", resp.getImages()));

            return existedFile.getFileId();
        };

        handlers.put("success", handlerSuccess);
        handlers.put("image_repeated", handlerRepeated);

    }
}
